package com.hm.car.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.querydsl.QPageRequest;
import org.springframework.stereotype.Component;

import com.hm.car.api.bean.OfferCallBackVo;
import com.hm.car.api.bean.OfferCallBackVo.CarInfoVo;
import com.hm.car.api.bean.OfferCallBackVo.CarOwnerVo;
import com.hm.car.api.bean.OfferCompanyVo;
import com.hm.car.api.bean.OfferUserVo;
import com.hm.car.api.bean.OrderDetailsVo;
import com.hm.car.api.bean.OrderDetailsVo.ProvidersVo;
import com.hm.car.model.OfferModel;
import com.hm.car.model.OfferUserModel;
import com.hm.car.model.QOfferModel;
import com.hm.car.model.QOfferUserModel;
import com.hm.car.repository.OfferRepository;
import com.hm.car.repository.OfferUserRepository;
import com.hm.car.util.BeanUtil;
import com.hm.common.su.bean.PageInfo;
import com.hm.common.util.CommonUtil;
import com.querydsl.core.types.dsl.BooleanExpression;

/**
 * @author shishun.wang
 * @date 2016年12月14日 上午9:56:25
 * @version 1.0
 * @describe
 */
@Component
public class OfferService {

	@Autowired
	private OfferUserRepository offerUserRepository;

	@Autowired
	private OfferRepository offerRepository;

	@Autowired
	private MongoTemplate mongoTemplate;

	public OfferUserVo loadOfferUser(String carLicenseNo) {
		OfferUserModel userModel = offerUserRepository.findOne(QOfferUserModel.offerUserModel.carLicenseNo.eq(carLicenseNo));
		if (CommonUtil.isEmpty(userModel)) {
			return null;
		}
		OfferUserVo user = new OfferUserVo();
		BeanUtil.copyProperties(userModel, user);
		return user;
	}

	public List<OfferUserVo> findOfferUser(String addUser) {

		List<OfferUserModel> userList = (List<OfferUserModel>) offerUserRepository.findAll(QOfferUserModel.offerUserModel.addUser.eq(addUser));
		if (CommonUtil.isEmpty(userList)) {
			return null;
		}
		List<OfferUserVo> list = new ArrayList<OfferUserVo>();
		for (OfferUserModel userModel : userList) {
			OfferUserVo user = new OfferUserVo();
			BeanUtil.copyProperties(userModel, user);
			list.add(user);
		}

		return list;
	}

	public void saveOfferUser(OfferUserVo user, String carLicenseNo) {
		OfferUserModel userModel = offerUserRepository.findOne(QOfferUserModel.offerUserModel.carLicenseNo.eq(carLicenseNo));
		if (CommonUtil.isEmpty(userModel)) {
			userModel = new OfferUserModel();
			BeanUtil.copyProperties(user, userModel);
			userModel.setCarLicenseNo(carLicenseNo);
			userModel.setCreateTime(new Date().getTime());
			userModel.setId(null);
			offerUserRepository.save(userModel);
		} else {
			String id = userModel.getId();
			BeanUtil.copyProperties(user, userModel);
			userModel.setCarLicenseNo(carLicenseNo);
			userModel.setCreateTime(CommonUtil.isNotEmpty(userModel) ? userModel.getCreateTime() : new Date().getTime());
			userModel.setId(id);
			offerUserRepository.save(userModel);
		}

	}

	public void updateOfferUser(OfferUserVo user, String carLicenseNo) throws Exception {
		OfferUserModel userModel = offerUserRepository.findOne(QOfferUserModel.offerUserModel.carLicenseNo.eq(carLicenseNo));
		if (CommonUtil.isEmpty(userModel)) {
			throw new Exception("该车牌号不存在");
		}
		String id = userModel.getId();
		BeanUtil.copyProperties(user, userModel);
		userModel.setCarLicenseNo(carLicenseNo);
		userModel.setCreateTime(CommonUtil.isNotEmpty(userModel) ? userModel.getCreateTime() : new Date().getTime());
		userModel.setId(id);
		offerUserRepository.save(userModel);
	}

	public void saveOffer(OfferCallBackVo callBackVo) {
		QOfferModel qOfferModel = QOfferModel.offerModel;

		OfferModel offerModel = offerRepository.findOne(qOfferModel.prvId.eq(callBackVo.getPrvId()).and(qOfferModel.taskId.eq(callBackVo.getTaskId())));

		String id = CommonUtil.isNotEmpty(offerModel) ? offerModel.getId() : null;

		OfferModel model = new OfferModel();
		BeanUtil.copyProperties(callBackVo, model);
		model.setCreateTime(new Date().getTime());
		model.setId(id);
		mongoTemplate.save(model);
	}

	public PageInfo<OrderDetailsVo> queryOrderDetails(int pageNumber, int pageSize, String addUser) {
		int totalSize = mongoTemplate.getCollection("insurance_offer").distinct("taskId").size();
		List<OrderDetailsVo> content = new ArrayList<OrderDetailsVo>();
		List<OrderDetailsVo> newcontent = new ArrayList<OrderDetailsVo>();
		int start = (pageNumber - 1) * pageSize;
		int end = pageNumber * pageSize;
		int totalPage = 1;
		if (totalSize % pageSize == 0) {
			totalPage = totalSize / pageSize;
		} else {
			totalPage = totalSize / pageSize + 1;
		}

		if (start >= totalSize) {
			return new PageInfo<OrderDetailsVo>(content, totalPage, totalSize);
		}

		@SuppressWarnings("rawtypes")
		List list = mongoTemplate.getCollection("insurance_offer").distinct("taskId").subList(start, (end > totalSize) ? totalSize : end);
		for (int i = 0; i < list.size(); i++) {
			String taskId = (String) list.get(i);
			content.add(getOrderDetail(taskId));
		}

		// 查询登陆用户下的车辆信息
		if (Integer.parseInt(addUser) >= 0) {
			List<OfferUserVo> userList = findOfferUser(addUser);
			if (userList != null && content != null) {
				for (OrderDetailsVo detailVO : content) {
					for (OfferUserVo userVO : userList) {
						if (detailVO.getCarInfo().getCarLicenseNo().equals(userVO.getCarLicenseNo())) {
							newcontent.add(detailVO);
						}
					}
				}
			}
		}

		return new PageInfo<OrderDetailsVo>(newcontent, pageNumber, pageSize);
	}

	public OrderDetailsVo getOrderDetail(String taskId) {
		CarInfoVo carInfo = null;
		CarOwnerVo carOwner = null;
		List<ProvidersVo> providers = new ArrayList<ProvidersVo>();
		List<OfferModel> models = mongoTemplate.find(new Query(Criteria.where("taskId").is(taskId)), OfferModel.class);
		for (OfferModel model : models) {
			ProvidersVo providersVo = new ProvidersVo();
			BeanUtil.copyProperties(model, providersVo);
			providersVo.setPrvCode(model.getTaskState());
			providersVo.setMsg(model.getMsg());
			providersVo.setPrvDesc(model.getTaskStateDescription());
			providersVo.setQuoteValidTime(model.getPayValidTime());
			providersVo.setTotalPrice(CommonUtil.isNotEmpty(model.getInsureInfo()) ? model.getInsureInfo().getTotalPremium() : "0.00");

			carInfo = model.getCarInfo();
			carOwner = model.getCarOwner();
			providers.add(providersVo);
		}
		String carLicenseNo = CommonUtil.isEmpty(carInfo) ? null : carInfo.getCarLicenseNo();
		OrderDetailsVo quoteBeanVo = new OrderDetailsVo();
		OfferUserVo user = loadOfferUser(carLicenseNo);
		if (CommonUtil.isNotEmpty(user)) {
			quoteBeanVo.setInsured(user);
			CarInfoVo carInfoVo = new CarInfoVo();
			BeanUtil.copyProperties(user, carInfoVo);
			quoteBeanVo.setCarInfo(carInfoVo);
		} else {
			quoteBeanVo.setInsured(carOwner);
			quoteBeanVo.setCarInfo(carInfo);
		}
		quoteBeanVo.setTaskId(taskId);
		quoteBeanVo.setProviders(providers);

		return quoteBeanVo;
	}

	public OfferCompanyVo getOfferCompany(String prvId, String taskId) {
		OfferModel model = mongoTemplate.findOne(new Query(Criteria.where("prvId").is(prvId)).addCriteria(Criteria.where("taskId").is(taskId)),
				OfferModel.class);
		if (CommonUtil.isEmpty(model)) {
			return null;
		}

		OfferCompanyVo offerCompanyVo = new OfferCompanyVo();
		BeanUtil.copyProperties(model, offerCompanyVo);
		offerCompanyVo.setInsureInfo(model.getInsureInfo());
		offerCompanyVo.setQuoteValidTime(model.getPayValidTime());
		offerCompanyVo.setPayValidTime(model.getPayValidTime());

		String carLicenseNo = CommonUtil.isEmpty(model.getCarInfo()) ? null : model.getCarInfo().getCarLicenseNo();

		OfferUserVo user = loadOfferUser(carLicenseNo);
		if (CommonUtil.isNotEmpty(user)) {
			offerCompanyVo.setCarOwner(user);
			offerCompanyVo.setApplicant(user);
			offerCompanyVo.setInsured(user);
			offerCompanyVo.setBeneficiary(user);

			CarInfoVo carInfoVo = new CarInfoVo();
			BeanUtil.copyProperties(user, carInfoVo);
			offerCompanyVo.setCarInfo(carInfoVo);
		} else {
			offerCompanyVo.setCarOwner(model.getCarOwner());
			offerCompanyVo.setApplicant(model.getCarOwner());
			offerCompanyVo.setInsured(model.getCarOwner());
			offerCompanyVo.setBeneficiary(model.getCarOwner());
			offerCompanyVo.setCarInfo(model.getCarInfo());
		}

		return offerCompanyVo;
	}

	public List<OfferModel> getOfferUserModelByUserId(String userId) {
		List<OfferModel> items = new ArrayList<OfferModel>();
		offerRepository.findAll(QOfferUserModel.offerUserModel.addUser.eq(userId)).forEach(user -> {
			List<OfferModel> offers = mongoTemplate.find(new Query(Criteria.where("carLicenseNo").is(user.getCarInfo().getCarLicenseNo())),
					OfferModel.class);
			if (CommonUtil.isEmpty(offers)) {
				return;
			}
			items.addAll(offers);
		});
		return items;
	}

	/**
	 * 根据条件查询车保
	 * 
	 * @param pageNumber
	 * @param pageSize
	 * @param addUser
	 * @param carLicenseNo
	 * @return
	 */
	public PageInfo getUserByCondition(int pageNumber, int pageSize, String addUser, String carLicenseNo) {

		QOfferUserModel offerusermodel = QOfferUserModel.offerUserModel;

		Pageable pageable = new QPageRequest(pageNumber, pageSize, offerusermodel.createTime.desc());

		BooleanExpression predicate = offerusermodel.addUser.isNotNull();

		if (CommonUtil.isNotEmpty(addUser)) {
			predicate = predicate.and(offerusermodel.addUser.eq(addUser));
		}

		if (CommonUtil.isNotEmpty(carLicenseNo)) {
			predicate = predicate.and(offerusermodel.carLicenseNo.eq(carLicenseNo));
		}

		Page<OfferUserModel> page = offerUserRepository.findAll(predicate, pageable);

		return new PageInfo(page.getContent(), page.getTotalPages(), page.getTotalElements());
	}

	/**
	 * 根据条件查询保单
	 * 
	 * @param pageNumber
	 * @param pageSize
	 * @param addUser
	 * @param carLicenseNo
	 * @return
	 */
	public PageInfo<OrderDetailsVo> getOfferModelByCondition(int pageNumber, int pageSize, String taskId, String carLicenseNo, String taskState, String addUser,
			Long begCreatTime, Long endCreatTime) {
		Criteria criteria = new Criteria();
		if (CommonUtil.isNotEmpty(taskId)) {
			criteria.and("taskId").is(taskId);
		}
		if (CommonUtil.isNotEmpty(carLicenseNo)) {
			criteria.and("carInfo.carLicenseNo").is(carLicenseNo);
		}
		if (CommonUtil.isNotEmpty(taskState)) {
			criteria.and("taskState").is(taskState);
		}
		if (CommonUtil.isNotEmpty(addUser)) {
			criteria.and("carOwner.name").is(addUser);
		}
		if (CommonUtil.isNotEmpty(endCreatTime) && CommonUtil.isNotEmpty(begCreatTime)) {
			criteria.and("createTime").gte(begCreatTime).and("createTime").lte(endCreatTime);
		}

		long totalSize = mongoTemplate.count(new Query(criteria), OfferModel.class);
		List<OrderDetailsVo> content = new ArrayList<OrderDetailsVo>();
		long start = (pageNumber - 1) * pageSize;
		long end = pageNumber * pageSize;
		long totalPage = 1;
		if (totalSize % pageSize == 0) {
			totalPage = totalSize / pageSize;
		} else {
			totalPage = totalSize / pageSize + 1;
		}

		if (start >= totalSize) {
			return new PageInfo<OrderDetailsVo>(content, (int) totalPage, totalSize);
		}

		List<OfferModel> list = mongoTemplate.find(new Query(criteria), OfferModel.class).subList((int) start,
				(end > totalSize) ? (int) totalSize : (int) end);
		for (OfferModel model : list) {
			content.add(getOrderDetail(model.getTaskId()));
		}

		return new PageInfo<OrderDetailsVo>(content, (int) totalPage, totalSize);
	}

}
